/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 spell_properties.h

	$Header: /heroes4/spell_properties.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( SPELL_PROPERTIES_H_INCLUDED )
#define SPELL_PROPERTIES_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <string>

enum t_creature_type;
enum t_spell;
enum t_town_type;

enum t_ai_spell_type
{
	k_ai_spell_type_none = -1,

	k_ai_spell_type_blessing,
	k_ai_spell_type_curse,
	k_ai_spell_type_damage,
	k_ai_spell_type_hand_of_death,
	k_ai_spell_type_healing,
	k_ai_spell_type_resurrection,
	k_ai_spell_type_sacrifice,
	k_ai_spell_type_summoning,

	k_ai_spell_type_count
};

enum t_spell_type
{
	k_spell_type_adventure,
	k_spell_type_affect_elemental,
	k_spell_type_affect_enemy,
	k_spell_type_affect_friend,
	k_spell_type_affect_mechanical,
	k_spell_type_affect_undead,
	k_spell_type_affects_defense,
	k_spell_type_affects_magic,
	k_spell_type_affects_offense,
	k_spell_type_blessing,     // can be cast on friendly creatures
	k_spell_type_cold,		
	k_spell_type_combat,
	k_spell_type_curse,        // can be cast on enemy creatures
	k_spell_type_damage,
	k_spell_type_fear,		   
	k_spell_type_fire,		
	k_spell_type_has_strength, // bonus affects spell's strength
	k_spell_type_healing,
	k_spell_type_high_priority,
	k_spell_type_line_of_sight, // requires line of sight
	k_spell_type_mass_effect,
	k_spell_type_mind,
	k_spell_type_physical,   // cannot be removed by antimagic spells
	k_spell_type_resisted,      // can be resisted by magic resistance
	k_spell_type_single_target, // targets a single square or creature
	k_spell_type_summoning,
	k_spell_type_targets_bodies,
	k_spell_type_teachable,	 // appears in mage guilds


	k_spell_type_count
};

int const k_spell_bit_adventure			= 1 << k_spell_type_adventure;
int const k_spell_bit_affect_elemental	= 1 << k_spell_type_affect_elemental;
int const k_spell_bit_affect_enemy		= 1 << k_spell_type_affect_enemy;
int const k_spell_bit_affect_friend		= 1 << k_spell_type_affect_friend;
int const k_spell_bit_affect_mechanical	= 1 << k_spell_type_affect_mechanical;
int const k_spell_bit_affect_undead	    = 1 << k_spell_type_affect_undead;
int const k_spell_bit_affects_defense	= 1 << k_spell_type_affects_defense;
int const k_spell_bit_affects_magic		= 1 << k_spell_type_affects_magic;
int const k_spell_bit_affects_offense	= 1 << k_spell_type_affects_offense;
int const k_spell_bit_blessing			= 1 << k_spell_type_blessing;
int const k_spell_bit_cold				= 1 << k_spell_type_cold;
int const k_spell_bit_combat			= 1 << k_spell_type_combat;
int const k_spell_bit_curse				= 1 << k_spell_type_curse;
int const k_spell_bit_damage			= 1 << k_spell_type_damage;
int const k_spell_bit_fear				= 1 << k_spell_type_fear;
int const k_spell_bit_fire				= 1 << k_spell_type_fire;
int const k_spell_bit_has_strength		= 1 << k_spell_type_has_strength;
int const k_spell_bit_healing			= 1 << k_spell_type_healing;
int const k_spell_bit_high_priority		= 1 << k_spell_type_high_priority;
int const k_spell_bit_line_of_sight		= 1 << k_spell_type_line_of_sight;
int const k_spell_bit_mass_effect		= 1 << k_spell_type_mass_effect;
int const k_spell_bit_mind				= 1 << k_spell_type_mind;
int const k_spell_bit_physical			= 1 << k_spell_type_physical;
int const k_spell_bit_resisted			= 1 << k_spell_type_resisted;
int const k_spell_bit_single_target		= 1 << k_spell_type_single_target;
int const k_spell_bit_summoning			= 1 << k_spell_type_summoning;
int const k_spell_bit_targets_bodies	= 1 << k_spell_type_targets_bodies;
int const k_spell_bit_teachable			= 1 << k_spell_type_teachable;


t_ai_spell_type get_ai_spell_type( t_spell spell );
int				get_ai_spell_value( t_spell spell );
int				get_basic_spell_power( t_spell spell, int level, int multiplier );
const char*		get_mage_guild_text( t_spell spell );
const char*		get_short_spell_name( t_spell spell );
t_spell			get_spell( std::string keyword );
t_town_type		get_spell_alignment( t_spell spell );
int				get_spell_cost( t_spell spell );
const char*		get_spell_flavor_text( t_spell spell );
const char*		get_spell_help( t_spell spell );
const char*		get_spell_keyword( t_spell spell );
int				get_spell_level( t_spell spell );
const char*		get_spell_name( t_spell spell );
const char*		get_spellbook_text( t_spell spell );
t_creature_type get_summoned_creature( t_spell );
bool			spell_is( t_spell spell, int spell_bits, bool all = false );


inline bool spell_is_type( t_spell spell, t_spell_type type )
{
	return spell_is( spell, 1 << type );
}

// note: this function (and bit) should only be used in simulated combat, since
// it abstracts some aspects of some spells
inline bool affects_defense( t_spell spell ) 
{
	return spell_is( spell, k_spell_bit_affects_defense );
}

inline bool affects_elementals( t_spell spell )
{
	return spell_is( spell, k_spell_bit_affect_elemental );
}

inline bool affects_enemies( t_spell spell )
{
	return spell_is( spell, k_spell_bit_affect_enemy );
}

inline bool affects_friends( t_spell spell )
{
	return spell_is( spell, k_spell_bit_affect_friend );
}

// note: this function (and bit) should only be used in simulated combat, since
// it abstracts some aspects of some spells
inline bool affects_magic( t_spell spell ) 
{
	return spell_is( spell, k_spell_bit_affects_magic );
}


inline bool affects_mechanical( t_spell spell )
{
	return spell_is( spell, k_spell_bit_affect_mechanical );
}


// note: this function (and bit) should only be used in simulated combat, since
// it abstracts some aspects of some spells
inline bool affects_offense( t_spell spell ) 
{
	return spell_is( spell, k_spell_bit_affects_offense );
}

inline bool affects_undead( t_spell spell )
{
	return spell_is( spell, k_spell_bit_affect_undead );
}

inline bool can_resist( t_spell spell )
{
	return spell_is( spell, k_spell_bit_resisted );
}

inline bool is_adventure( t_spell spell )
{
	return spell_is( spell, k_spell_bit_adventure );
}

inline bool is_blessing( t_spell spell )
{
	return spell_is( spell, k_spell_bit_blessing );
}

inline bool is_cold( t_spell spell )
{
	return spell_is( spell, k_spell_bit_cold );
}

inline bool is_combat( t_spell spell )
{
	return spell_is( spell, k_spell_bit_combat );
}

inline bool is_curse( t_spell spell )
{
	return spell_is( spell, k_spell_bit_curse );
}

inline bool is_damage( t_spell spell )
{
	return spell_is( spell, k_spell_bit_damage );
}

inline bool is_fear( t_spell spell )
{
	return spell_is( spell, k_spell_bit_fear );
}

inline bool is_fire( t_spell spell )
{
	return spell_is( spell, k_spell_bit_fire );
}

inline bool is_high_priority( t_spell spell )
{
	return spell_is( spell, k_spell_bit_high_priority );
}

inline bool has_strength( t_spell spell )
{
	return spell_is( spell, k_spell_bit_has_strength );
}

inline bool is_healing( t_spell spell )
{
	return spell_is( spell, k_spell_bit_healing );
}

inline bool is_line_of_sight( t_spell spell )
{
	return spell_is( spell, k_spell_bit_line_of_sight );
}

// note: this function (and bit) should only be used in simulated combat, since
// it abstracts some aspects of some spells
inline bool is_mass_effect( t_spell spell ) 
{
	return spell_is( spell, k_spell_bit_mass_effect );
}

inline bool is_mind( t_spell spell )
{
	return spell_is( spell, k_spell_bit_mind );
}

inline bool is_physical( t_spell spell )
{
	return spell_is( spell, k_spell_bit_physical );
}

inline bool is_single_target( t_spell spell )
{
	return spell_is( spell, k_spell_bit_single_target );
}

inline bool is_summoning( t_spell spell )
{
	return spell_is( spell, k_spell_bit_summoning );
}

inline bool is_teachable( t_spell spell )
{
	return spell_is( spell, k_spell_bit_teachable );
}

inline bool targets_bodies( t_spell spell )
{
	return spell_is( spell, k_spell_bit_targets_bodies );
}

int		get_mage_guild_spell_count( int spell_level, bool library = false );
t_spell translate_spell( t_spell spell );

int const k_haste_speed_increase = 3;
int const k_haste_move_increase = 900;
int const k_spell_shackle_damage = 10;

#endif